""" Working draft of the 2nd (technically 3rd) resource management system.

    TODO:   Find a way to use SQlite for managing metadata while still
            keeping weak references to copies of resource objects.
"""

import weakref
import sqlite3 as sql

def init():
    """ Initializes the catalog system.
    
        This must be called before using the module. It takes care of
        setting up the resource database and a few other things.
    """
    global _con, _cur
    # Create the database and the connection.
    _con = sql.connect(":memory:")
    _cur = _con.cursor()


class Catalog(object):
    """ Basic resource catalog class.
    
        This is basically a combination of an sqlite3 table and a
        weak value dictionary. The table is stored inside a database
        that is created when the module is initialized (meaning this
        class won't work at all until the module is initialized) and
        holds metadata about each resource in the catalog. The
        dictionary holds references to loaded resources.
    """
    
    def __init__(self, table, cols=None, md=None):
        """ Inititialze an AbstractCalaog object.
            
            table:  Name of the table in the master database to use
                    with this catalog. (String, required.)
            cols:   Names of columns mapped to type specifications.
                    (Dictionary, optional.)
                    NOTE: You do not need to explicitly pass rules for
                    the 'id' and 'src' columns; if either is absent, it
                    will be added with the correct types automatically.
                    (Please see the source code for guidelines on how
                    to define these columns.) Also note that the 'id'
                    column will ALWAYS be made the primary key.
            md:     Sequence of intial metadata to populate the table.
                    Each item is either another sequence giving the
                    values for each column in the order defined by the
                    `cols` argument or a dictionary which maps column
                    names to values. (Optional.)
        
            Subclasses should call this at initialization.
        """
        # Create a dictionary if none is given
        if cols is None:
            cols = {}
        
        # Add required columns if they are missing.
        if 'id' not in cols:
            cols['id'] = "TEXT NOT NULL PRIMARY KEY"
        if 'src' not in cols:
            cols['src'] = "TEXT NOT NULL"
        
        # Create the column definition list.
        colrules = ', '.join(["%s %s"%(k,v) for k,v in cols.iteritems]) + ')'
        
        # Create the table.
        _cur.execute('CREATE TABLE :table (:colrules, PRIMARY KEY id)',
                     {"table":table, "colrules":colrules})
        
        # Create the resource weak reference mapping.
        self._res = weakref.WeakValueDictionary()

    def add(self, *rows):
        """ Add a one or more rows of data to the metadata database.
        
            Each row may be either a sequence containing the values of the
            new row in the order that the columns were defined or a
            dictionary which maps column names to values.
        """
        for r in rows:
            _cur.execute('INSERT INTO %s (%s) VALUES (?)'%
                         (self._table, ', '.join(r.keys())),
                         [', '.join(r.values())])

    def get(self, id):
        """ Returns the resource with the given id.
        
            When this method is first called it will create a
            
    